/**
 * Copyright (c) 2018-2028, HQY 胡庆一 (215218393@qq.com).
 * <p>
 * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.gnu.org/licenses/lgpl.html
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.ocm.product.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.ocm.product.dto.AuditProductDTO;
import com.ocm.product.dto.SpuDTO;
import com.ocm.product.dto.SpuSearchDTO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import lombok.AllArgsConstructor;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;

import lombok.SneakyThrows;
import com.ocm.core.log.exception.ServiceException;
import com.ocm.core.mp.support.Condition;
import com.ocm.core.mp.support.Query;
import com.ocm.core.secure.BladeUser;
import com.ocm.core.tool.api.R;
import com.ocm.core.tool.constant.RoleConstant;
import com.ocm.core.tool.utils.Func;
import com.ocm.core.tool.utils.StringUtil;
import com.ocm.product.entity.Sku;
import com.ocm.product.service.ISkuService;
import com.ocm.product.vo.SpuDetailVO;
import com.ocm.product.vo.SpuSearchVO;
import com.ocm.warehouse.feign.IStockClient;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestParam;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.ocm.product.entity.Spu;
import com.ocm.product.vo.SpuVO;
import com.ocm.product.wrapper.SpuWrapper;
import com.ocm.product.service.ISpuService;
import com.ocm.core.boot.ctrl.BladeController;
import springfox.documentation.annotations.ApiIgnore;

import java.util.Date;
import java.util.Map;

/**
 *  控制器
 *
 * @author HQY
 * @since 2021-11-18
 */
@RestController
@AllArgsConstructor
@RequestMapping("/spu")
@Api(value = "", tags = "接口")
public class SpuController extends BladeController {

	private final ISpuService spuService;

	private final ISkuService skuService;

	private final IStockClient stockClient;


	/**
	 * 详情
	 */
	@SneakyThrows
	@GetMapping("/detail")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "详情", notes = "传入spu")
	public R<SpuDetailVO> detail(Long spuId) {
		return  R.data(spuService.detail(spuId));

	}

	/**
	 * 分页
	 */
	@GetMapping("/list")
	@ApiOperationSupport(order = 2)
	@ApiOperation(value = "分页", notes = "传入spu")
	public R<IPage<SpuVO>> list(Spu spu, Query query) {
		IPage<Spu> pages = spuService.page(Condition.getPage(query), Condition.getQueryWrapper(spu));
		return R.data(SpuWrapper.build().pageVO(pages));
	}


	@SneakyThrows
	@GetMapping("/search")
	@ApiOperationSupport(order = 2)
	@ApiOperation(value = "商品搜索", notes = "传入SpuSearchDTO")
	public R<IPage<SpuSearchVO>> search(SpuSearchDTO search, Query query) {
		IPage<SpuSearchVO> pages = spuService.searchSpu(search, query);
		return R.data(pages);
	}



	/**
	 * 自定义分页
	 */
	@GetMapping("/page")
	@ApiOperationSupport(order = 3)
	@ApiOperation(value = "分页", notes = "传入spu")
	public R<IPage<SpuVO>> page(@ApiIgnore @RequestParam Map<String, Object> spuVO, Query query) {

		//重命名status列名（由于status涉及多表相同字段）
		QueryWrapper<SpuVO> queryWrapper;
		if(spuVO.containsKey("status")){
			Object t=spuVO.get("status");
			spuVO.remove("status");
			queryWrapper=Condition.getQueryWrapper(spuVO, SpuVO.class).eq("p.status",t);
		}else {
			queryWrapper=Condition.getQueryWrapper(spuVO, SpuVO.class);
		}

		IPage<SpuVO> pages = spuService.selectSpuPage(Condition.getPage(query),queryWrapper.eq("p.is_deleted",0).groupBy("p.id"));
		return R.data(pages);
	}


	/**
	 * 新增商品
	 */
	@PostMapping("/save")
	@ApiOperationSupport(order = 4)
	@ApiOperation(value = "新增", notes = "传入spu")
	@Transactional
	public R save(@Valid @RequestBody SpuDTO spuDTO, BladeUser bladeUser) {
		return R.status(spuService.saveProduct(spuDTO,bladeUser));
	}


	/**
	 * 修改 编辑后自动修改为待审核
	 */
	@PostMapping("/update")
	@ApiOperationSupport(order = 5)
	@ApiOperation(value = "修改", notes = "传入spu")
	public R update(@Valid @RequestBody Spu spu,BladeUser bladeUser) {
		if(spu.getStatus()==3)
			return R.fail("请先下架商品");
		@NotNull Spu s = spuService.getById(spu.getId());
		//判断当前商品是否可以进行操作
		if(s.getShopId().equals(bladeUser.getShopId())||StringUtil.containsAny(bladeUser.getRoleName(), RoleConstant.ADMIN)) {
			if(spu.getStatus()==2)spu.setStatus(1);
			return R.status(spuService.updateById(spu));
		}
		return R.fail("非法操作");
	}
	/**
	 * 修改状态 仅允许用户修改为待审核 下架
	 */
	@PostMapping("/status")
	@ApiOperationSupport(order = 5)
	@ApiOperation(value = "修改", notes = "传入spu")
	public R status(@RequestBody Spu spu,BladeUser bladeUser) {
		if(spu.getStatus()==3||spu.getStatus()==2)
			return R.fail("非法操作");
		@NotNull Spu s = spuService.getById(spu.getId());
		//判断当前商品是否可以进行操作
		if(s.getShopId().equals(bladeUser.getShopId())||StringUtil.containsAny(bladeUser.getRoleName(), RoleConstant.ADMIN)) {
			return R.status(spuService.update(new UpdateWrapper<Spu>().set("status",spu.getStatus()).eq("id",spu.getId())));
		}
		return R.fail("非法操作");
	}


	/**
	 * 审核
	 */
	@PostMapping("/audit")
	@ApiOperationSupport(order = 10)
	@ApiOperation(value = "修改", notes = "传入spu")
	@Transactional
	public R audit(@Valid @RequestBody AuditProductDTO auditProductDTO, BladeUser bladeUser) {
		if(auditProductDTO.getStatus()==0||auditProductDTO.getStatus()==2){
			return R.status(spuService.update(new UpdateWrapper<Spu>()
					.set("status",auditProductDTO.getStatus())
					.set("audit_remark",auditProductDTO.getAuditRemark())
					.set("audit_user",bladeUser.getUserId())
					.set("audit_time",new Date())
					.eq("id",auditProductDTO.getId())
					.eq("status",1)
					.eq("is_deleted",0)
				));

		}
		return R.fail("非法操作");

	}
	/**
	 * 上架
	 */
	@PostMapping("/putaway")
	@ApiOperationSupport(order = 10)
	@ApiOperation(value = "上架", notes = "传入spu")
	@Transactional
	public R putaway(@NotNull @RequestParam Long spuId, BladeUser bladeUser) {
		@NotNull SpuVO spu = spuService.getSpuVo(spuId);
		//判断当前商品是否可以进行操作
		if(spu.getStatus()==2&&(spu.getShopId().equals(bladeUser.getShopId())||StringUtil.containsAny(bladeUser.getRoleName(), RoleConstant.ADMIN))){
			R<Boolean> res = stockClient.hasStockBySpuId(spu.getId());
			if(!res.isSuccess()){
				throw new ServiceException(res.getMsg());
			}
			if(!res.getData()){
				return R.fail("该商品有规格库存为0哦");
			}
			if(!spuService.putaway(spu)){
				return R.fail("商品信息保存失败,等一会再试试");
			}
			spu.setStatus(3);
			spuService.update(new UpdateWrapper<Spu>()
				.set("status",3)
				.eq("id",spuId)
			);
			return R.success("上架成功");
		}
		return R.fail("非法操作");
	}

	@PostMapping("/soldOut")
	@ApiOperationSupport(order = 10)
	@ApiOperation(value = "下架", notes = "传入spu")
	@Transactional
	public R soldOut(@NotNull @RequestParam Long spuId, BladeUser bladeUser) {
		@NotNull Spu spu = spuService.getById(spuId);
		//判断当前商品是否可以进行操作
		if(spu.getStatus()==3&&(spu.getShopId().equals(bladeUser.getShopId())||StringUtil.containsAny(bladeUser.getRoleName(), RoleConstant.ADMIN))){
			spu.setStatus(2);
			spuService.soldOut(spuId);
			spuService.update(new UpdateWrapper<Spu>()
				.set("status",0)
				.eq("id",spuId)
			);
			return R.success("下架成功");
		}
		return R.fail("非法操作");
	}



	/**
	 * 新增或修改
	 */
	@PostMapping("/submit")
	@ApiOperationSupport(order = 6)
	@ApiOperation(value = "新增或修改", notes = "传入spu")
	public R submit(@Valid @RequestBody Spu spu) {
		return R.status(spuService.saveOrUpdate(spu));
	}


	/**
	 * 删除
	 */
	@PostMapping("/remove")
	@ApiOperationSupport(order = 7)
	@ApiOperation(value = "逻辑删除", notes = "传入ids")
	@Transactional
	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
		skuService.getBaseMapper().delete(new QueryWrapper<Sku>().in("spu_id",ids));
		return R.status(spuService.deleteLogic(Func.toLongList(ids)));
	}


}
